﻿using Microsoft.ApplicationServer.Caching;
using Microsoft.Ted.Wacel.TestConsole.Properties;
using Microsoft.WindowsAzure.Storage;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Ted.Wacel.TestConsole
{
    public class TableTester
    {
        public static void InsertAndRead()
        {
            Table<Customer> customers = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            customers.Clear();

            customers.Insert(new Customer { ID = 100, Name = "This is a cool customer.", Value = 123.456 });
            var readback = customers.Read("100");
            VisualTester.AreEqual(100, readback.ID);
            VisualTester.AreEqual("This is a cool customer.", readback.Name);
            VisualTester.AreEqual(123.456, readback.Value);
        }
        public static void Replace()
        {
            Table<Customer> customers = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            customers.Clear();

            customers.Insert(new Customer { ID = 100, Name = "This is a cool customer.", Value = 123.456 });
            var readback = customers.Read("100");

            readback.Name = "This is a new name.";
            customers.Replace(readback);

            var readback2 = customers.Read("100");

            VisualTester.AreEqual(100, readback2.ID);
            VisualTester.AreEqual("This is a new name.", readback2.Name);
            VisualTester.AreEqual(123.456, readback2.Value);
        }
        public static void MultiReplaces()
        {
            Table<Customer> customers = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            customers.Clear();

            customers.Insert(new Customer { ID = 100, Name = "This is a cool customer.", Value = 123.456 });
            string Etag = null;
            var readback = customers.Read("100",out Etag);

            readback.Name = "This is a new name.";
            customers.Replace(readback);

            readback.Name = "This is another new name.";
            customers.Replace(readback);

            var readback2 = customers.Read("100");
            VisualTester.AreEqual("This is another new name.", readback2.Name);
        }
        public static void Update()
        {
            Table<Customer> customers = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            customers.Clear();

            customers.Insert(new Customer { ID = 100, Name = "This is a cool customer.", Value = 123.456 });
            string Etag = null;
            var readback = customers.Read("100", out Etag);

            readback.Name = "This is a new name.";
            customers.Update(readback, Etag);

            var readback2 = customers.Read("100");
            VisualTester.AreEqual("This is a new name.", readback2.Name);
        }
        public static void MultipleUpdates()
        {
            Table<Customer> customers = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            customers.Clear();

            customers.Insert(new Customer { ID = 100, Name = "This is a cool customer.", Value = 123.456 });
            var readback = customers.Read("100");

            readback.Name = "This is a new name.";
            customers.Update(readback);

            readback.Name = "This is another new name.";
            customers.Update(readback);

            var readback2 = customers.Read("100");
            VisualTester.AreEqual("This is another new name.", readback2.Name);
        }
        public static void BasicPageTest()
        {
            Table<Customer> storage = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            storage.Clear();

            DateTime time = DateTime.UtcNow;

            for (int i = 0; i < 100; i++)
                storage.Insert(new Customer { ID = i, Name = "This is a customer " + i.ToString(), Value = i + 0.5, Time = time });

            Stopwatch watch = new Stopwatch();
            watch.Start();
            var customers = storage.List("50", "59");
            watch.Stop();
            Console.WriteLine("First list: " + watch.ElapsedMilliseconds);
            for (int i = 0; i < 5; i ++ )
            {
                watch.Restart();
                customers = storage.List("50", "59");
                watch.Stop();
                Console.WriteLine("Cached list: " + watch.ElapsedMilliseconds);
                VisualTester.AreEqual(10, customers.Count());
                VisualTester.AreEqual("This is a customer 50", customers.First().Name);
            }
        }
        public static void FailedUpdateWithExplicitConcurrencyCheck()
        {
            Table<Customer> customers = new Table<Customer>("ID", Settings.Default.StorageConnectionString, "customers", new DataCache());

            customers.Clear();

            customers.Insert(new Customer { ID = 100, Name = "This is a cool customer.", Value = 123.456 });
            string Etag = null;
            string Etag2 = null;
            var readback = customers.Read("100", out Etag);
            var readback2 = customers.Read("100", out Etag2);

            VisualTester.AreEqual(Etag, Etag2);

            readback.Name = "This is a new name.";
            customers.Update(readback, Etag);

            try
            {
                readback2.Name = "This is another new name.";
                customers.Update(readback2, Etag);
                VisualTester.Assert(false, "Expected StorageException");
            }
            catch (StorageException)
            {
                VisualTester.Assert(true);
            }
            catch (Exception exp)
            {
                VisualTester.Assert(false, exp.Message);
            }
        }
    }
}
